/*
 * @Author: sjf 1758142861@qq.com
 * @Date: 2023-03-31 19:06:46
 * @LastEditors: sjf 1758142861@qq.com
 * @LastEditTime: 2023-04-03 18:46:51
 * @FilePath: /sjf/lwp/block_queue/again_test/count_test.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include"count.hpp"
#include"forward_blockqueue.hpp"
#include<sys/types.h>
#include<ctime>
#include<unistd.h>

// template<class C,class S>
// class BlockQueues
// {
// public:
//     Anwtie::BlockQueue<C> *c_bq;
//     Anwtie::BlockQueue<S> *s_bq;
// };

// void*productor(void* args)
// {
//     Anwtie::BlockQueue<CalTask>* bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->c_bq;
//     while(true)
//     {
//         sleep(1);
//         int x = rand() % 100;
//         int y = rand() % 10;
//         int op = rand() % oper.size();
//         CalTask t(x,y,oper[op],mymath);
//         bq->push(t);
//         std::cout << "productor thread, 生产计算任务: " << t.To_taskstring() << std::endl;
//     }
//     return nullptr;
// }

// void* consumer(void* args)
// {
//     Anwtie::BlockQueue<CalTask>* bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->c_bq;
//     Anwtie::BlockQueue<CalTask>* save_bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->s_bq;
//     while(true)
//     {
//         sleep(1);
//         CalTask t;
//         bq->pop(&t);
//         std::string result = t();
//         std::cout << "cal thread,完成计算任务: " << result << " ... done"<< std::endl;
//         SaveTask save(result,Save);
//         save_bq->push(save);
//         std::cout << "cal thread,推送存储任务完成..." << std::endl; 
//     }
//     return nullptr;
// }

// void *saver(void *args)
// {
//     Anwtie::BlockQueue<CalTask>* save_bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->s_bq;

//     while(true)
//     {
//         SaveTask t;
//         save_bq->pop(&t);
//         t();
//         std::cout << "save thread,保存任务完成..." << std::endl; 
//     }
//     return nullptr;
// }


template<class C, class S>
class BlockQueues
{
public:
    Anwtie::BlockQueue<C> *c_bq;
    Anwtie::BlockQueue<S> *s_bq;
};

void *productor(void *bqs_)
{
    Anwtie::BlockQueue<CalTask> *bq = (static_cast<BlockQueues<CalTask, SaveTask> *>(bqs_))->c_bq;
    // BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(bq_);
    while (true)
    {
         sleep(1);
        // 生产活动,从数据库？从网络，从外设？？拿来的用户数据！！
        int x = rand() % 100 + 1; // 在这里我们先用随机数，构建一个数据
        int y = rand() % 10;
        int operCode = rand() % oper.size();
        CalTask t(x, y, oper[operCode], mymath);


        bq->push(t);
        std::cout << "productor thread, 生产计算任务: " << t.To_taskstring() << std::endl;
        
    }
    return nullptr;
}

void *consumer(void *bqs_)
{
    Anwtie::BlockQueue<CalTask> *bq = (static_cast<BlockQueues<CalTask, SaveTask> *>(bqs_))->c_bq;
    Anwtie::BlockQueue<SaveTask> *save_bq = (static_cast<BlockQueues<CalTask, SaveTask> *>(bqs_))->s_bq;

    while (true)
    {
        // 消费活动
        CalTask t;
        bq->pop(&t);

        std::string result = t(); // 任务非常耗时！！
        std::cout << "cal thread,完成计算任务: " << result << " ... done"<< std::endl;

        SaveTask save(result, Save);
        save_bq->push(save);
        std::cout << "cal thread,推送存储任务完成..." << std::endl; 

        sleep(1);
    }
    return nullptr;
}

void *saver(void *bqs_)
{
    Anwtie::BlockQueue<SaveTask> *save_bq = (static_cast<BlockQueues<CalTask, SaveTask> *>(bqs_))->s_bq;

    while(true)
    {
        SaveTask t;
        save_bq->pop(&t);
        t();
        std::cout << "save thread,保存任务完成..." << std::endl; 
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr) ^ getpid());
    BlockQueues<CalTask,SaveTask> bqs;
    bqs.c_bq = new Anwtie::BlockQueue<CalTask>();
    bqs.s_bq = new Anwtie::BlockQueue<SaveTask>();

    pthread_t c[2], p[3], s;

    pthread_create(p, nullptr, productor, &bqs);
    pthread_create(p+1, nullptr, productor, &bqs);
    pthread_create(p+2, nullptr, productor, &bqs);
    pthread_create(c, nullptr, consumer, &bqs);
    pthread_create(c+1, nullptr, consumer, &bqs);

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    pthread_join(p[2], nullptr);

    delete bqs.c_bq;
    delete bqs.s_bq;
    
    return 0;
}